<template>
  <div>
    <el-form :model="formConfig" size="mini" label-position="left" label-width="120px" class="setting-form"
      @submit.native.prevent>
      <el-collapse v-model="formActiveCollapseNames" class="setting-collapse">
        <el-collapse-item name="1" :title="i18nt('designer.setting.basicSetting')">
          <el-form-item :label="i18nt('designer.setting.formSize')">
            <el-select v-model="formConfig.size">
              <el-option v-for="item in formSizes" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.labelPosition')">
            <el-radio-group v-model="formConfig.labelPosition" class="radio-group-custom">
              <el-radio-button label="left">{{
                i18nt("designer.setting.leftPosition")
              }}</el-radio-button>
              <el-radio-button label="top">{{
                i18nt("designer.setting.topPosition")
              }}</el-radio-button>
            </el-radio-group>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.h5LabelTop')">
            <el-switch v-model="formConfig.h5LabelTop"></el-switch>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.labelAlign')">
            <el-radio-group v-model="formConfig.labelAlign" class="radio-group-custom">
              <el-radio-button label="label-left-align">{{
                i18nt("designer.setting.leftAlign")
              }}</el-radio-button>
              <el-radio-button label="label-center-align">{{
                i18nt("designer.setting.centerAlign")
              }}</el-radio-button>
              <el-radio-button label="label-right-align">{{
                i18nt("designer.setting.rightAlign")
              }}</el-radio-button>
            </el-radio-group>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.labelWidth')">
            <el-input-number v-model="formConfig.labelWidth" :min="0" style="width: 100%"></el-input-number>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.gridResponsive')">
            <el-switch v-model="formConfig.gridResponsive"></el-switch>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.formCss')">
            <el-button type="info" icon="el-icon-edit" plain round @click="editFormCss">{{
              i18nt("designer.setting.addCss") }}</el-button>
          </el-form-item>
          <!-- -->
          <el-form-item :label="i18nt('designer.setting.customClass')">
            <el-select v-model="formConfig.customClass" multiple filterable allow-create default-first-option>
              <el-option v-for="(item, idx) in cssClassList" :key="idx" :label="item" :value="item"></el-option>
            </el-select>
          </el-form-item>
          <!-- -->
          <template v-if="showEventCollapse()">
            <el-form-item :label="i18nt('designer.setting.globalFunctions')">
              <el-button type="info" icon="el-icon-edit" plain round @click="editGlobalFunctions">{{
                i18nt("designer.setting.addEventHandler") }}</el-button>
            </el-form-item>
            <el-form-item label-width="0">
              <el-divider class="custom-divider">{{
                i18nt("designer.setting.formSFCSetting")
              }}</el-divider>
            </el-form-item>
            <el-form-item :label="i18nt('designer.setting.formModelName')">
              <el-input type="text" v-model="formConfig.modelName"></el-input>
            </el-form-item>
            <el-form-item :label="i18nt('designer.setting.formRefName')">
              <el-input type="text" v-model="formConfig.refName"></el-input>
            </el-form-item>
            <el-form-item :label="i18nt('designer.setting.formRulesName')">
              <el-input type="text" v-model="formConfig.rulesName"></el-input>
            </el-form-item>
          </template>
        </el-collapse-item>

        <el-collapse-item v-if="showEventCollapse()" name="2" :title="i18nt('designer.setting.eventSetting')">
          <el-form-item label="onFormCreated" label-width="150px">
            <el-button type="info" icon="el-icon-edit" plain round :class="[
              getFormEventHandled('onFormCreated')
                ? 'button-text-highlight'
                : '',
            ]" @click="editFormEventHandler('onFormCreated')">
              {{ i18nt("designer.setting.addEventHandler") }}</el-button>
          </el-form-item>
          <el-form-item label="onFormMounted" label-width="150px">
            <el-button type="info" icon="el-icon-edit" plain round :class="[
              getFormEventHandled('onFormMounted')
                ? 'button-text-highlight'
                : '',
            ]" @click="editFormEventHandler('onFormMounted')">
              {{ i18nt("designer.setting.addEventHandler") }}</el-button>
          </el-form-item>
          <!-- -->
          <el-form-item label="onFormDataChange" label-width="150px">
            <el-button type="info" icon="el-icon-edit" plain round :class="[
              getFormEventHandled('onFormDataChange')
                ? 'button-text-highlight'
                : '',
            ]" @click="editFormEventHandler('onFormDataChange')">
              {{ i18nt("designer.setting.addEventHandler") }}</el-button>
          </el-form-item>
          <!-- -->
          <el-form-item label="onFormValidate" label-width="150px">
            <el-button type="info" icon="el-icon-edit" plain round :class="[
              getFormEventHandled('onFormValidate')
                ? 'button-text-highlight'
                : '',
            ]" @click="editFormEventHandler('onFormValidate')">
              {{ i18nt("designer.setting.addEventHandler") }}</el-button>
          </el-form-item>
        </el-collapse-item>
        <el-collapse-item name="3" title="规则设置">
          <el-table :data="tableData" style="width: 100%">
            <el-table-column prop="date" label="序号">
              <template slot-scope="scope">
                {{ scope.$index + 1 }}
              </template>
            </el-table-column>
            <el-table-column prop="ruleName" label="规则名称"> </el-table-column>
            <el-table-column prop="address" label="更多">
              <template slot-scope="scope">
                <el-dropdown @command="handleCommand">
                  <span class="el-dropdown-link">
                    <i class="el-icon-more"></i>
                  </span>
                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item :command="beforeHandleCommand('del', {
                      row: scope.row,
                      index: scope.$index,
                    })
                      ">删除</el-dropdown-item>

                    <el-dropdown-item :command="beforeHandleCommand('editor', {
                      row: scope.row,
                      index: scope.$index,
                    })
                      ">
                      编辑
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </el-dropdown>
              </template>
            </el-table-column>
          </el-table>
          <div class="addBtncon">
            <el-button type="primary" @click="rulesDesc" class="addRules">规则详情</el-button>
          </div>
        </el-collapse-item>
      </el-collapse>
    </el-form>

    <el-dialog :title="i18nt('designer.setting.editFormEventHandler')" :visible.sync="showFormEventDialogFlag"
      v-if="showFormEventDialogFlag" :show-close="true" class="small-padding-dialog" v-dialog-drag append-to-body
      :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
      <el-alert type="info" :closable="false" :title="'form.' + eventParamsMap[curEventName]"></el-alert>
      <code-editor :mode="'javascript'" :readonly="false" v-model="formEventHandlerCode" ref="ecEditor"></code-editor>
      <el-alert type="info" :closable="false" title="}"></el-alert>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showFormEventDialogFlag = false">
          {{ i18nt("designer.hint.cancel") }}</el-button>
        <el-button type="primary" @click="saveFormEventHandler">
          {{ i18nt("designer.hint.confirm") }}</el-button>
      </div>
    </el-dialog>

    <el-dialog :title="i18nt('designer.setting.formCss')" :visible.sync="showEditFormCssDialogFlag"
      v-if="showEditFormCssDialogFlag" :show-close="true" class="small-padding-dialog" v-dialog-drag append-to-body
      :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
      <code-editor :mode="'css'" :readonly="false" v-model="formCssCode"></code-editor>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showEditFormCssDialogFlag = false">
          {{ i18nt("designer.hint.cancel") }}</el-button>
        <el-button type="primary" @click="saveFormCss">
          {{ i18nt("designer.hint.confirm") }}</el-button>
      </div>
    </el-dialog>

    <el-dialog :title="i18nt('designer.setting.globalFunctions')" :visible.sync="showEditFunctionsDialogFlag"
      v-if="showEditFunctionsDialogFlag" :show-close="true" class="small-padding-dialog" v-dialog-drag append-to-body
      :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
      <code-editor :mode="'javascript'" :readonly="false" v-model="functionsCode" ref="gfEditor"></code-editor>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showEditFunctionsDialogFlag = false">
          {{ i18nt("designer.hint.cancel") }}</el-button>
        <el-button type="primary" @click="saveGlobalFunctions">
          {{ i18nt("designer.hint.confirm") }}</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import i18n from "@/utils/i18n";
import CodeEditor from "@/components/code-editor/index";
import {
  deepClone,
  insertCustomCssToHead,
  insertGlobalFunctionsToHtml,
} from "@/utils/util";

export default {
  name: "form-setting",
  mixins: [i18n],
  components: {
    CodeEditor,
  },
  props: {
    designer: Object,
    formConfig: Object,
  },
  inject: ["getDesignerConfig", "tableDataArry"],
  computed: {
    tableData() {
      return this.tableDataArry();
    }
  },
  data() {
    return {
      designerConfig: this.getDesignerConfig(),

      // formActiveCollapseNames: ['1', '2',"3"],
      formActiveCollapseNames: ["3"],

      formSizes: [
        { label: "default", value: "" },
        { label: "large", value: "large" },
        { label: "medium", value: "medium" },
        { label: "small", value: "small" },
        { label: "mini", value: "mini" },
      ],

      showEditFormCssDialogFlag: false,
      formCssCode: "",
      cssClassList: [],

      showEditFunctionsDialogFlag: false,
      functionsCode: "",

      showFormEventDialogFlag: false,
      formEventHandlerCode: "",
      curEventName: "",

      eventParamsMap: {
        onFormCreated: "onFormCreated() {",
        onFormMounted: "onFormMounted() {",
        onFormDataChange:
          "onFormDataChange(fieldName, newValue, oldValue, formModel, subFormName, subFormRowIndex) {",
        onFormValidate: "onFormValidate(formModel) {",
      },

      time: null
    };
  },

  created() {
    //导入表单JSON后需要重新加载自定义CSS样式！！！
    this.designer.handleEvent("form-json-imported", () => {
      this.formCssCode = this.formConfig.cssCode;
      insertCustomCssToHead(this.formCssCode);
      this.extractCssClass();
      this.designer.emitEvent("form-css-updated", deepClone(this.cssClassList));
    });
  },
  mounted() {
    console.log(this.designer);

    /* SettingPanel和FormWidget为兄弟组件, 在FormWidget加载formConfig时，
       此处SettingPanel可能无法获取到formConfig.cssCode, 故加个延时函数！ */
    setTimeout(() => {
      this.formCssCode = this.formConfig.cssCode;
      insertCustomCssToHead(this.formCssCode);
      this.extractCssClass();
      this.designer.emitEvent("form-css-updated", deepClone(this.cssClassList));
    }, 3000);

  },
  methods: {

    handleCommand(command) {
      if (command.command == "del") {
        this.delItem(command.row, command.index);
      } else {
        this.editorItem(command.row, command.index);
      }
    },
    delItem(row, index) {
      this.designer.emitEvent("delItemDesigner", { row, index });
    },
    editorItem(row, index) {
      this.designer.emitEvent("editorItemDesigner", { row, index });
    },
    beforeHandleCommand(command, { row, index }) {
      return {
        command: command,
        row,
        index,
      };
    },

    getFormEventHandled(eventName) {
      return (
        !!this.formConfig[eventName] && this.formConfig[eventName].length > 0
      );
    },

    showEventCollapse() {
      if (this.designerConfig["eventCollapse"] === undefined) {
        return true;
      }

      return !!this.designerConfig["eventCollapse"];
    },

    editFormCss() {
      this.formCssCode = this.designer.formConfig.cssCode;
      this.showEditFormCssDialogFlag = true;
    },

    extractCssClass() {
      let regExp = /\..*{/g;
      let result = this.formCssCode.match(regExp);
      let cssNameArray = [];

      if (!!result && result.length > 0) {
        result.forEach((rItem) => {
          let classArray = rItem.split(","); //切分逗号分割的多个class
          if (classArray.length > 0) {
            classArray.forEach((cItem) => {
              let caItem = cItem.trim();
              if (caItem.indexOf(".", 1) !== -1) {
                //查找第二个.位置
                let newClass = caItem.substring(
                  caItem.indexOf(".") + 1,
                  caItem.indexOf(".", 1)
                ); //仅截取第一、二个.号之间的class
                if (!!newClass) {
                  cssNameArray.push(newClass.trim());
                }
              } else if (caItem.indexOf(" ") !== -1) {
                //查找第一个空格位置
                let newClass = caItem.substring(
                  caItem.indexOf(".") + 1,
                  caItem.indexOf(" ")
                ); //仅截取第一、二个.号之间的class
                if (!!newClass) {
                  cssNameArray.push(newClass.trim());
                }
              } else {
                if (caItem.indexOf("{") !== -1) {
                  //查找第一个{位置
                  let newClass = caItem.substring(
                    caItem.indexOf(".") + 1,
                    caItem.indexOf("{")
                  );
                  cssNameArray.push(newClass.trim());
                } else {
                  let newClass = caItem.substring(caItem.indexOf(".") + 1);
                  cssNameArray.push(newClass.trim());
                }
              }
            });
          }
        });
      }

      //this.cssClassList.length = 0
      this.cssClassList.splice(0, this.cssClassList.length); //清除数组必须用splice，length=0不会响应式更新！！
      this.cssClassList = Array.from(new Set(cssNameArray)); //数组去重
    },

    saveFormCss() {
      this.extractCssClass();
      this.designer.formConfig.cssCode = this.formCssCode;
      insertCustomCssToHead(this.formCssCode);
      this.showEditFormCssDialogFlag = false;

      this.designer.emitEvent("form-css-updated", deepClone(this.cssClassList));
    },

    editGlobalFunctions() {
      this.functionsCode = this.designer.formConfig.functions;
      this.showEditFunctionsDialogFlag = true;
    },

    saveGlobalFunctions() {
      const codeHints = this.$refs.gfEditor.getEditorAnnotations();
      let syntaxErrorFlag = false;
      if (!!codeHints && codeHints.length > 0) {
        codeHints.forEach((chItem) => {
          if (chItem.type === "error") {
            syntaxErrorFlag = true;
          }
        });

        if (syntaxErrorFlag) {
          this.$confirm(
            this.i18nt("designer.setting.syntaxCheckWarning"),
            this.i18nt("render.hint.prompt"),
            {
              confirmButtonText: this.i18nt("render.hint.forcedSave"),
              cancelButtonText: this.i18nt("render.hint.cancel"),
            }
          )
            .then(() => {
              this.designer.formConfig.functions = this.functionsCode;
              insertGlobalFunctionsToHtml(this.functionsCode);
              this.showEditFunctionsDialogFlag = false;
            })
            .catch((error) => {
              //
            });

          return;
        }
      }

      this.designer.formConfig.functions = this.functionsCode;
      insertGlobalFunctionsToHtml(this.functionsCode);
      this.showEditFunctionsDialogFlag = false;
    },

    editFormEventHandler(eventName) {
      this.curEventName = eventName;
      this.formEventHandlerCode = this.formConfig[eventName];
      this.showFormEventDialogFlag = true;
    },

    saveFormEventHandler() {
      const codeHints = this.$refs.ecEditor.getEditorAnnotations();
      let syntaxErrorFlag = false;
      if (!!codeHints && codeHints.length > 0) {
        codeHints.forEach((chItem) => {
          if (chItem.type === "error") {
            syntaxErrorFlag = true;
          }
        });

        if (syntaxErrorFlag) {
          this.$confirm(
            this.i18nt("designer.setting.syntaxCheckWarning"),
            this.i18nt("render.hint.prompt"),
            {
              confirmButtonText: this.i18nt("render.hint.forcedSave"),
              cancelButtonText: this.i18nt("render.hint.cancel"),
            }
          )
            .then(() => {
              this.$set(
                this.formConfig,
                this.curEventName,
                this.formEventHandlerCode
              );
              this.showFormEventDialogFlag = false;
            })
            .catch((error) => {
              //
            });

          return;
        }
      }

      //this.formConfig[this.curEventName] = this.formEventHandlerCode
      /* 注意：如果是options新增的事件属性，保存事件代码必须使用$set方法，！！ */
      this.$set(this.formConfig, this.curEventName, this.formEventHandlerCode);
      this.showFormEventDialogFlag = false;
    },

    rulesDesc() {
      this.designer.emitEvent("rulesDesc");
    },
  },
};
</script>

<style lang="scss" scoped>
.addBtncon {
  display: flex;
  justify-content: center;

  .addRules {
    margin-top: 10px;
  }
}

.setting-form {
  ::v-deep .el-form-item__label {
    font-size: 13px;
    //text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  }

  ::v-deep .el-form-item--mini.el-form-item {
    margin-bottom: 6px;
  }

  .radio-group-custom {
    ::v-deep .el-radio-button__inner {
      padding-left: 12px;
      padding-right: 12px;
    }
  }

  .custom-divider.el-divider--horizontal {
    margin: 10px 0;
  }
}

.setting-collapse {
  ::v-deep .el-collapse-item__content {
    padding-bottom: 6px;
  }

  ::v-deep .el-collapse-item__header {
    font-style: italic;
    font-weight: bold;
  }
}

.small-padding-dialog {
  ::v-deep .el-dialog__body {
    padding: 6px 15px 12px 15px;
  }
}

// .red{
//   color: red;
//   background: red;
//   width: 100%;
// }</style>
